package com.radar.task.cd;

import cn.hutool.core.exceptions.UtilException;

@SuppressWarnings("all")
/** 
* @author: fy-wbj 
* @description: 覆盖代码注释
* @date: 2022/6/2 
*/ 
public class BitConverter {

    //public static byte[] getBytes(double x)
    public static byte[] getBytes(double x) {
        return getBytes(Double.doubleToRawLongBits(x));
    }

    // public static byte[] getBytes(double[] data)
    public static byte[] getBytes(double[] data) {
        byte[] b = new byte[8 * data.length];
        int index = 0;
        for (int i = 0; i < data.length; i++) {
            getBytes(data[i], b, index);
            index += 8;
        }
        return b;
    }

    /**
     * public static byte[] getBytes(double[][] data)
     * @param data
     * @return
     */
    public static byte[] getBytes(double[][] data) {
        byte[] b = new byte[8 * data.length * data[0].length];
        int index = 0;
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[0].length; j++) {
                getBytes(data[i][j], b, index);
                index += 8;
            }
        }
        return b;
    }

    /**
     * public static void getBytes(double x, byte[] b, int index)
     * @param x
     * @param b
     * @param index
     */
    public static void getBytes(double x, byte[] b, int index) {
        getBytes(Double.doubleToRawLongBits(x), b, index);
    }

    /**
     * public static byte[] getBytes(short x)
     * @param x
     * @return
     */
    public static byte[] getBytes(short x) {
        return new byte[]{(byte) x, (byte) (x >>> 8)};
    }

    /**
     * public static void getBytes(short x, byte[] b, int index)
     * @param x
     * @param b
     * @param index
     */
    public static void getBytes(short x, byte[] b, int index) {
        b[index] = (byte) x;
        b[index + 1] = (byte) (x >>> 8);
    }

    /**
     * public static byte[] getBytesInverse(short x)
     * @param x
     * @return
     */
    public static byte[] getBytesInverse(short x) {
        return new byte[]{(byte) (x >>> 8), (byte) x};
    }

    /**
     * public static void getBytesInverse(short x, byte[] b, int index)
     * @param x
     * @param b
     * @param index
     */
    public static void getBytesInverse(short x, byte[] b, int index) {
        b[index + 1] = (byte) x;
        b[index] = (byte) (x >>> 8);
    }

    /**
     * public static byte[] getBytes(int x)
     * @param x
     * @return
     */
    public static byte[] getBytes(int x) {
        return new byte[]{(byte) x, (byte) (x >>> 8), (byte) (x >>> 16),
                (byte) (x >>> 24)};
    }

    /**
     * public static void getBytes(int x, byte[] b, int index)
     * @param x
     * @param b
     * @param index
     */
    public static void getBytes(int x, byte[] b, int index) {
        b[index] = (byte) x;
        b[index + 1] = (byte) (x >>> 8);
        b[index + 2] = (byte) (x >>> 16);
        b[index + 3] = (byte) (x >>> 24);
    }

    /**
     * public static byte[] getBytes(long x)
     * @param x
     * @return
     */
    public static byte[] getBytes(long x) {
        return new byte[]{(byte) x, (byte) (x >>> 8),
                (byte) (x >>> 16), (byte) (x >>> 24), (byte) (x >>> 32),
                (byte) (x >>> 40), (byte) (x >>> 48), (byte) (x >>> 56)};
    }

    /**
     * public static void getBytes(long x, byte[] b, int index)
     * @param x
     * @param b
     * @param index
     */
    public static void getBytes(long x, byte[] b, int index) {
        b[index] = (byte) x;
        b[index + 1] = (byte) (x >>> 8);
        b[index + 2] = (byte) (x >>> 16);
        b[index + 3] = (byte) (x >>> 24);
        b[index + 4] = (byte) (x >>> 32);
        b[index + 5] = (byte) (x >>> 40);
        b[index + 6] = (byte) (x >>> 48);
        b[index + 7] = (byte) (x >>> 56);
    }

    /**
     *  public static byte[] getBytes(float x)
     * @param x
     * @return
     */
    public static byte[] getBytes(float x) {
        return getBytes(Float.floatToRawIntBits(x));
    }

    /**
     * public static byte[] getBytes(float[] data)
     * @param data
     * @return
     */
    public static byte[] getBytes(float[] data) {
        byte[] b = new byte[4 * data.length];
        int index = 0;
        for (int i = 0; i < data.length; i++) {
            getBytes(data[i], b, index);
            index += 4;
        }
        return b;
    }

    /**
     * public static byte[] getBytes(float[][] data)
     * @param data
     * @return
     */
    public static byte[] getBytes(float[][] data) {
        byte[] b = new byte[4 * data.length * data[0].length];
        int index = 0;
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[0].length; j++) {
                getBytes(data[i][j], b, index);
                index += 4;
            }
        }
        return b;
    }

    public static byte[] getBytes(float[][][] data) {
        byte[] b = new byte[4 * data.length * data[0].length *data[0][0].length];
        int index = 0;
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[0].length; j++) {
                for (int k = 0 ; j < data[0][0].length; k ++) {
                    getBytes(data[i][j][k], b, index);
                    index += 4;
                }
            }
        }
        return b;
    }

    /**
     * public static byte[] getBytes(byte[][] data)
     * @param data
     * @return
     */
    public static byte[] getBytes(byte[][] data) {
        byte[] b = new byte[data.length * data[0].length];
        int index = 0;
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[0].length; j++) {
                b[index] = data[i][j];
                index++;
            }
        }
        return b;
    }

    /**
     * public static void getBytes(float x, byte[] b, int index)
     * @param x
     * @param b
     * @param index
     */
    public static void getBytes(float x, byte[] b, int index) {
        getBytes(Float.floatToRawIntBits(x), b, index);
    }

    /**
     * public static byte[] getBytes(String x)
     * @param x
     * @return
     */
    public static byte[] getBytes(String x) {
        return x.getBytes();
    }

    /**
     * public boolean toBoolean(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public boolean toBoolean(byte[] bytes, int index) {
        if (bytes.length != 1)
            throw new UtilException(
                    "The length of the byte array must be at least 1 byte long.");
        return bytes[index] != 0;
    }

    /**
     * public static double toDouble(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public static double toDouble(byte[] bytes, int index) {
        if (bytes.length - index < 8) {
            throw new UtilException(
                    "The length of the byte array must be at least 8 bytes long.");
        }
        return Double.longBitsToDouble(toInt64(bytes, index));
    }

    /**
     * public static short toInt16(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public static short toInt16(byte[] bytes, int index) {
        if (bytes.length - index < 2) {
            throw new UtilException(
                    "The length of the byte array must be at least 2 bytes long.");
        }
        return (short) ((0xff & bytes[index]) << 0 | (0xff & bytes[index + 1]) << 8);
    }

    /**
     * public static short toInt16Inverse(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public static short toInt16Inverse(byte[] bytes, int index) {
        if (bytes.length - index < 2)
            throw new UtilException(
                    "The length of the byte array must be at least 4 bytes long.");

        return (short) ((0xff & bytes[index + 1]) << 0 | (0xff & bytes[index]) << 8);
    }

    /**
     * public static int toInt32(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public static int toInt32(byte[] bytes, int index) {
        if (bytes.length - index < 4)
            throw new UtilException(
                    "The length of the byte array must be at least 4 bytes long.");

        return ((0xff & bytes[index + 3]) << 56
                | (0xff & bytes[index + 2]) << 48
                | (0xff & bytes[index + 1]) << 40 |
                (0xff & bytes[index]) << 32);
    }

    /**
     * public static int toInt32Inverse(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public static int toInt32Inverse(byte[] bytes, int index) {
        if (bytes.length - index < 4)
            throw new UtilException(
                    "The length of the byte array must be at least 4 bytes long.");

        return ((0xff & bytes[index]) << 56
                | (0xff & bytes[index + 1]) << 48
                | (0xff & bytes[index + 2]) << 40 |
                (0xff & bytes[index + 3]) << 32);
    }

    /**
     * public static long toInt64(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public static long toInt64(byte[] bytes, int index) {
        if (bytes.length - index < 8)
            throw new UtilException(
                    "The length of the byte array must be at least 8 bytes long.");
        return ((long) (0xff & bytes[index + 7]) << 56
                | (long) (0xff & bytes[index + 6]) << 48
                | (long) (0xff & bytes[index + 5]) << 40
                | (long) (0xff & bytes[index + 4]) << 32
                | (long) (0xff & bytes[index + 3]) << 24
                | (long) (0xff & bytes[index + 2]) << 16
                | (long) (0xff & bytes[index + 1]) << 8 |
                (long) (0xff & bytes[index]));
    }

    /**
     * public static float toSingle(byte[] bytes, int index)
     * @param bytes
     * @param index
     * @return
     */
    public static float toSingle(byte[] bytes, int index) {
        if (bytes.length - index < 4)
            throw new UtilException(
                    "The length of the byte array must be at least 4 bytes long.");
        return Float.intBitsToFloat(toInt32(bytes, index));
    }

    /**
     * public static String toString(byte[] bytes)
     * @param bytes
     * @return
     */
    public static String toString(byte[] bytes) {
        if (bytes == null)
            throw new UtilException("The byte array must have at least 1 byte.");
        return new String(bytes);
    }
}
